#include <QToolTip>
#include "updownwidget.h"

UpDownWidget::UpDownWidget(QWidget *pParent)
: QWidget(pParent)
, m_leftSpace(10)
, m_rightSpace(50)
, m_bottomSpace(20)
{
    setMouseTracking(true);
    Account *account = Account::inst();
    account->addListener(this);
}

void UpDownWidget::onAccountChanged()
{
    update();
}

void UpDownWidget::paintEvent(QPaintEvent* event)
{
    event->accept();
    QPainter paint(this);
    QMatrix m;
    m.translate(0.0, static_cast<float>(height())-1);
    m.scale(1.f, -1.f);
    paint.setMatrix(m);

    paint.setMatrixEnabled(true);
    paint.setRenderHint(QPainter::Antialiasing, false);
    paint.setPen(Qt::NoPen);

    //QBrush brush(QColor(199, 237, 204));
    QBrush brush(QColor(204, 232, 207));
    brush.setStyle(Qt::SolidPattern);
    paint.setBrush(brush);
    paint.drawRect(0, 0, width() - 1, height() - 1);

    setupPara();
    drawLines(paint);
    drawUpDown(paint);
    paint.setMatrixEnabled(false);
}

void UpDownWidget::mousePressEvent(QMouseEvent *event)
{
    event->accept();
    QPoint mousePos = event->pos();
    int w = event->globalX();
    int h = event->globalY();
    if (event->button() == Qt::LeftButton) {
        QString strHint, strBalance;
        int index = mouseToIndex(event->x());
        strHint = "No: " + QString::number(index);
        Account *account = Account::inst();
        const std::vector<HistBalance> vecHistBalance = account->getHistBalance();
        int size = vecHistBalance.size();
        if (index < size) {
            strBalance = "\nBalance: " + QString::number(vecHistBalance[index].m_balance, 'g');
        }
        QToolTip::showText(QPoint(w, h), strHint + strBalance, this);
    }
}

void UpDownWidget::drawLines(QPainter &paint)
{
    Account *account = Account::inst();
    const std::vector<HistBalance> vecHistBalance = account->getHistBalance();
    int size = vecHistBalance.size();
    int lineSpace = 30;
    int lineNum = ( height() - m_bottomSpace) / lineSpace;
    if (size == 0)
        return;
    QPen pen;
    pen.setStyle(Qt::DashDotLine);
    pen.setColor(Qt::gray);
    paint.setPen(pen);
    for (int i = 0; i <= lineNum; ++i) {
        int h = i * lineSpace + m_bottomSpace;
        double val = m_minVal + (m_maxVal - m_minVal) * ((double)(i * lineSpace)/(height() - m_bottomSpace));
        paint.drawLine(QLine(m_leftSpace, h, width() - m_rightSpace, h));
        //
        paint.scale(-1.f, 1.f);
        paint.rotate(180.f);
        paint.drawText(QPoint(width() - m_rightSpace, -h + 6), QString::number(val, 'g', 6));
        paint.rotate(180.f);
        paint.scale(-1.f, 1.f);
    }

    lineNum = ( width() - m_leftSpace - m_rightSpace) / lineSpace;
    int orderForward = size / lineNum;
    if (orderForward < 1) orderForward = 1;
    for (int i = 0; i < size; i = i + orderForward) {
        paint.scale(-1.f, 1.f);
        paint.rotate(180.f);
        paint.drawText(QPoint(getWidth(i), -m_bottomSpace + 10), QString::number(i, 'g', 6));
        paint.rotate(180.f);
        paint.scale(-1.f, 1.f);
    }
}

void UpDownWidget::drawUpDown(QPainter &paint)
{
    Account *account = Account::inst();
    const std::vector<HistBalance> vecHistBalance = account->getHistBalance();
    int size = vecHistBalance.size();
    if (size == 0)
        return;
    double *arrWidth  = new double[size];
    double *arrHeight = new double[size];
    for (int i = 0; i < size; ++i) {
        arrWidth[i] = getWidth(i);
        arrHeight[i] = getHeight(vecHistBalance[i].m_balance);
    }
    QPen pen;
    pen.setStyle(Qt::SolidLine);
    pen.setColor(Qt::black);
    pen.setWidth(2.0);
    paint.setPen(pen);
    for (int i = 0; i < size - 1; ++i){
        paint.drawLine(arrWidth[i], arrHeight[i], arrWidth[i+1], arrHeight[i+1]);
    }
    delete []arrWidth;
    delete []arrHeight;
}

void UpDownWidget::setupPara()
{
    Account *account = Account::inst();
    const std::vector<HistBalance> vecHistBalance = account->getHistBalance();
    int size = vecHistBalance.size();
    int currWidth = width() - m_leftSpace - m_rightSpace;
    if (size <= 10) {
        m_space = 30;
    }
    else {
        m_space = 1.0 / size * currWidth;
    }
    m_maxVal = account->getMaxBalance();
    m_minVal = account->getMinBalance();
    if (m_maxVal <= m_minVal)
        m_minVal = m_maxVal - 1;
}

int UpDownWidget::mouseToIndex(int pos) {
    return (pos - m_leftSpace + m_space / 2) / m_space;
}